package com.yc.thread.basic;

import java.util.Random;

/**
 * @author zwei
 * @create 2024-07-15 16:33
 */
public class Test17_producerConsumer {
    public static void main(String[] args) {
        AppleBox appleBox = new AppleBox();
        //创建生产者
        Producer p1 = new Producer(appleBox);
        Producer p2 = new Producer(appleBox);
        Producer p3 = new Producer(appleBox);
        //创建消费者
        Consumer c1 = new Consumer(appleBox);

        //已上是任务
        new Thread(p1, "生产者1").start();
        new Thread(p2, "生产者2").start();
        new Thread(p3, "生产者3").start();
        new Thread(c1, "消费者1").start();
    }
}

class Apple {
    String id;

    Apple(String id) {
        this.id = id;
    }

    @Override
    public String toString() {
        return "apple:" + id;
    }
}

//中间消息件：存消息(apple)
class AppleBox {
    Apple[] apples = new Apple[5];  //最多存五个
    int index = 0;    //index表示当前有几条消息

    //生产后存消息
    public synchronized void deposite(Apple apple) {
        while (index == apples.length) {
            try {
                this.wait();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
//            try {
//                Thread.sleep(1000);     //消息存满后  睡眠一秒
//            } catch (InterruptedException e) {
//                throw new RuntimeException(e);
//            }
        }
        this.notifyAll();
        apples[index] = apple;
        index++;
    }

    //消费消息
    public synchronized Apple withdraw() {
        while (index == 0) {
            try {
                this.wait();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
//            try {
//                Thread.sleep(1000);
//            } catch (InterruptedException e) {
//                throw new RuntimeException(e);
//            }
        }
//        this.notifyAll();
        index--;
        return apples[index];
    }
}

//生产消息的任务
class Producer implements Runnable {
    AppleBox ab = null;

    public Producer(AppleBox ab) {
        this.ab = ab;
    }

    @Override
    public void run() {
        Random random = new Random();
        for (int i = 0; i < 5; i++) {
            Apple a = new Apple(Thread.currentThread().getName() + "牌：" + i);
            ab.deposite(a);
            System.out.println(Thread.currentThread().getName() + "生产了：" + a);
            try {
                Thread.sleep(random.nextInt(1000));
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

//消费消息的任务
class Consumer implements Runnable {
    AppleBox ab = null;       //生产完的消息要存放到 applebox中

    public Consumer(AppleBox ab) {
        this.ab = ab;
    }

    @Override
    public void run() {
        Random random = new Random();
        //从
//        while (ab.index > 0) {
        while (true){
//            for(int i=1;i<5;i++){
            Apple a = ab.withdraw();
            System.out.println(Thread.currentThread().getName() + "消费了：" + a);
            try {
                Thread.sleep(random.nextInt(1000));
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            //}
        }
    }
}
